package service

import (
	"context"
	"encoding/json"
	"fmt"
	"strconv"
	"strings"
	"sysu-giep/internal/database/models"
	"sysu-giep/pkg/logger"
	"time"

	"github.com/olivere/elastic/v7"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

type ProjectService struct {
	db       *gorm.DB
	esClient *elastic.Client
}

func NewProjectService(db *gorm.DB, esClient *elastic.Client) *ProjectService {
	return &ProjectService{
		db:       db,
		esClient: esClient,
	}
}

// GetProjects 获取课题列表
func (s *ProjectService) GetProjects(page, size int, keyword, category, status string, priority int, location, skills string, budgetMin, budgetMax float64, isPublic string) ([]models.Project, int64, error) {
	var projects []models.Project
	var total int64

	query := s.db.Model(&models.Project{})

	// 应用筛选条件
	if keyword != "" {
		query = query.Where("title LIKE ? OR description LIKE ? OR requirements LIKE ?",
			"%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
	}

	if category != "" {
		query = query.Where("category = ?", category)
	}

	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 新增筛选条件
	if priority > 0 {
		query = query.Where("priority = ?", priority)
	}

	if location != "" {
		query = query.Where("location = ?", location)
	}

	if skills != "" {
		query = query.Where("skills LIKE ?", "%"+skills+"%")
	}

	if budgetMin > 0 {
		query = query.Where("budget >= ?", budgetMin)
	}

	if budgetMax > 0 {
		query = query.Where("budget <= ?", budgetMax)
	}

	if isPublic != "" {
		if isPublic == "true" {
			query = query.Where("is_public = ?", true)
		} else if isPublic == "false" {
			query = query.Where("is_public = ?", false)
		}
	}

	// 只返回已发布的课题
	query = query.Where("status = ?", models.ProjectStatusOpen)

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * size
	if err := query.Preload("Creator").
		Order("priority DESC, created_at DESC").
		Offset(offset).
		Limit(size).
		Find(&projects).Error; err != nil {
		return nil, 0, err
	}

	return projects, total, nil
}

// GetProjectByID 根据ID获取课题详情
func (s *ProjectService) GetProjectByID(id uint64) (*models.Project, error) {
	var project models.Project

	if err := s.db.Preload("Creator").
		Preload("Applications.Applicant").
		First(&project, id).Error; err != nil {
		return nil, err
	}

	return &project, nil
}

// CreateProject 创建课题
func (s *ProjectService) CreateProject(project *models.Project) error {
	// 设置默认状态
	if project.Status == "" {
		project.Status = models.ProjectStatusOpen
	}

	// 创建课题
	if err := s.db.Create(project).Error; err != nil {
		return err
	}

	// 同步到Elasticsearch
	if s.esClient != nil {
		if err := s.IndexProject(project); err != nil {
			logger.ErrorLog("同步课题到Elasticsearch失败", zap.Uint64("project_id", uint64(project.ID)), zap.Error(err))
		}
	}

	return nil
}

// UpdateProject 更新课题
func (s *ProjectService) UpdateProject(id uint64, updates map[string]interface{}) error {
	// 更新课题
	if err := s.db.Model(&models.Project{}).Where("id = ?", id).Updates(updates).Error; err != nil {
		return err
	}

	// 同步到Elasticsearch
	if s.esClient != nil {
		if err := s.UpdateProjectIndex(id, updates); err != nil {
			logger.ErrorLog("更新Elasticsearch索引失败", zap.Uint64("project_id", id), zap.Error(err))
		}
	}

	return nil
}

// DeleteProject 删除课题
func (s *ProjectService) DeleteProject(id uint64) error {
	// 删除课题
	if err := s.db.Delete(&models.Project{}, id).Error; err != nil {
		return err
	}

	// 从Elasticsearch删除索引
	if s.esClient != nil {
		if err := s.DeleteProjectIndex(id); err != nil {
			logger.ErrorLog("删除Elasticsearch索引失败", zap.Uint64("project_id", id), zap.Error(err))
		}
	}

	return nil
}

// GetMyProjects 获取我的课题
func (s *ProjectService) GetMyProjects(userID uint64, page, size int, status string) ([]models.Project, int64, error) {
	var projects []models.Project
	var total int64

	query := s.db.Model(&models.Project{}).Where("creator_id = ?", userID)

	// 应用状态筛选
	if status != "" {
		query = query.Where("status = ?", status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * size
	if err := query.Preload("Creator").
		Order("created_at DESC").
		Offset(offset).
		Limit(size).
		Find(&projects).Error; err != nil {
		return nil, 0, err
	}

	return projects, total, nil
}

// ApplyProject 申请课题
func (s *ProjectService) ApplyProject(application *models.Application) error {
	// 创建申请记录
	if err := s.db.Create(application).Error; err != nil {
		return err
	}

	// 更新课题申请人数
	if err := s.db.Model(&models.Project{}).
		Where("id = ?", application.ProjectID).
		UpdateColumn("apply_count", gorm.Expr("apply_count + ?", 1)).Error; err != nil {
		return err
	}

	return nil
}

// GetProjectCategories 获取课题分类
func (s *ProjectService) GetProjectCategories() ([]map[string]interface{}, error) {
	var categories []map[string]interface{}

	// 从数据库获取分类统计
	rows, err := s.db.Model(&models.Project{}).
		Select("category, COUNT(*) as count, AVG(budget) as avg_budget").
		Group("category").
		Rows()
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	for rows.Next() {
		var category string
		var count int
		var avgBudget float64

		if err := rows.Scan(&category, &count, &avgBudget); err != nil {
			continue
		}

		categories = append(categories, map[string]interface{}{
			"name":       category,
			"count":      count,
			"avg_budget": avgBudget,
		})
	}

	return categories, nil
}

// FavoriteProject 收藏课题
func (s *ProjectService) FavoriteProject(userID, projectID uint64) error {
	favorite := &models.ProjectFavorite{
		UserID:     uint(userID),
		ProjectID:  uint(projectID),
		FavoriteAt: time.Now(),
		Note:       "",
	}

	return s.db.Create(favorite).Error
}

// UnfavoriteProject 取消收藏课题
func (s *ProjectService) UnfavoriteProject(userID, projectID uint64) error {
	return s.db.Where("user_id = ? AND project_id = ?", userID, projectID).
		Delete(&models.ProjectFavorite{}).Error
}

// GetFavoriteProjects 获取收藏的课题
func (s *ProjectService) GetFavoriteProjects(userID uint64, page, size int) ([]models.Project, int64, error) {
	var projects []models.Project
	var total int64

	// 通过收藏表关联查询课题
	query := s.db.Model(&models.Project{}).
		Joins("JOIN project_favorites ON projects.id = project_favorites.project_id").
		Where("project_favorites.user_id = ?", userID)

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, err
	}

	// 分页查询
	offset := (page - 1) * size
	if err := query.Preload("Creator").
		Order("project_favorites.created_at DESC").
		Offset(offset).
		Limit(size).
		Find(&projects).Error; err != nil {
		return nil, 0, err
	}

	return projects, total, nil
}

// UpdateProjectStatus 更新课题状态
func (s *ProjectService) UpdateProjectStatus(userID, projectID uint64, newStatus string) error {
	// 验证用户权限
	project, err := s.GetProjectByID(projectID)
	if err != nil {
		return err
	}

	if project.CreatorID != uint(userID) {
		return fmt.Errorf("无权限更新该课题状态")
	}

	// 更新状态
	return s.db.Model(&models.Project{}).
		Where("id = ?", projectID).
		Update("status", newStatus).Error
}

// HasActiveApplications 检查课题是否有进行中的申请
func (s *ProjectService) HasActiveApplications(projectID uint64) (bool, error) {
	var count int64

	err := s.db.Model(&models.Application{}).
		Where("project_id = ? AND status IN (?)", projectID, []string{
			string(models.ApplicationStatusPending),
			string(models.ApplicationStatusAccepted),
		}).
		Count(&count).Error

	return count > 0, err
}

// HasUserApplied 检查用户是否已经申请过该课题
func (s *ProjectService) HasUserApplied(projectID, userID uint64) (bool, error) {
	var count int64

	err := s.db.Model(&models.Application{}).
		Where("project_id = ? AND applicant_id = ?", projectID, userID).
		Count(&count).Error

	return count > 0, err
}

// HasUserFavorited 检查用户是否已经收藏过该课题
func (s *ProjectService) HasUserFavorited(projectID, userID uint64) (bool, error) {
	var count int64

	err := s.db.Model(&models.ProjectFavorite{}).
		Where("project_id = ? AND user_id = ?", projectID, userID).
		Count(&count).Error

	return count > 0, err
}

// SearchProjects 使用Elasticsearch搜索课题
func (s *ProjectService) SearchProjects(query string, page, size int, field string, budgetMin, budgetMax float64, durationMin, durationMax int) ([]models.Project, int64, error) {
	if s.esClient == nil {
		// 如果Elasticsearch不可用，回退到数据库搜索
		return s.GetProjects(page, size, query, field, "", 0, "", "", budgetMin, budgetMax, "")
	}

	// 构建搜索查询
	searchQuery := elastic.NewBoolQuery()

	// 关键词搜索
	if query != "" {
		// 多字段搜索
		multiMatchQuery := elastic.NewMultiMatchQuery(query, "title^3", "description^2", "requirements^2", "category^1.5").
			Type("best_fields").
			Fuzziness("AUTO")
		searchQuery.Must(multiMatchQuery)
	}

	// 研究方向筛选
	if field != "" {
		searchQuery.Filter(elastic.NewTermQuery("category", field))
	}

	// 预算范围筛选
	if budgetMin > 0 || budgetMax > 0 {
		rangeQuery := elastic.NewRangeQuery("budget")
		if budgetMin > 0 {
			rangeQuery.Gte(budgetMin)
		}
		if budgetMax > 0 {
			rangeQuery.Lte(budgetMax)
		}
		searchQuery.Filter(rangeQuery)
	}

	// 时长范围筛选
	if durationMin > 0 || durationMax > 0 {
		rangeQuery := elastic.NewRangeQuery("duration")
		if durationMin > 0 {
			rangeQuery.Gte(durationMin)
		}
		if durationMax > 0 {
			rangeQuery.Lte(durationMax)
		}
		searchQuery.Filter(rangeQuery)
	}

	// 只搜索已发布的课题
	searchQuery.Filter(elastic.NewTermQuery("status", string(models.ProjectStatusOpen)))

	// 执行搜索
	searchResult, err := s.esClient.Search().
		Index("projects").
		Query(searchQuery).
		Sort("_score", false).     // 按相关性排序
		Sort("created_at", false). // 然后按创建时间排序
		From((page - 1) * size).
		Size(size).
		Do(context.Background())

	if err != nil {
		logger.ErrorLog("Elasticsearch search failed", zap.Error(err))
		return nil, 0, err
	}

	// 解析搜索结果
	var projects []models.Project
	for _, hit := range searchResult.Hits.Hits {
		var project models.Project
		if err := json.Unmarshal(hit.Source, &project); err != nil {
			logger.ErrorLog("Failed to unmarshal project", zap.Error(err))
			continue
		}
		projects = append(projects, project)
	}

	total := searchResult.TotalHits()

	logger.Info("Elasticsearch search completed",
		zap.String("query", query),
		zap.Int("page", page),
		zap.Int("size", size),
		zap.Int64("total", total),
		zap.Int("results", len(projects)),
	)

	return projects, total, nil
}

// IndexProject 将课题索引到Elasticsearch
func (s *ProjectService) IndexProject(project *models.Project) error {
	if s.esClient == nil {
		return fmt.Errorf("elasticsearch client not initialized")
	}

	_, err := s.esClient.Index().
		Index("projects").
		Id(strconv.FormatUint(uint64(project.ID), 10)).
		BodyJson(project).
		Do(context.Background())

	if err != nil {
		logger.ErrorLog("Failed to index project to Elasticsearch",
			zap.Uint64("project_id", uint64(project.ID)),
			zap.Error(err))
		return err
	}

	logger.Info("Project indexed to Elasticsearch", zap.Uint64("project_id", uint64(project.ID)))
	return nil
}

// UpdateProjectIndex 更新Elasticsearch中的课题索引
func (s *ProjectService) UpdateProjectIndex(projectID uint64, updates map[string]interface{}) error {
	if s.esClient == nil {
		return fmt.Errorf("elasticsearch client not initialized")
	}

	_, err := s.esClient.Update().
		Index("projects").
		Id(strconv.FormatUint(projectID, 10)).
		Doc(updates).
		Do(context.Background())

	if err != nil {
		logger.ErrorLog("Failed to update project index in Elasticsearch",
			zap.Uint64("project_id", projectID),
			zap.Error(err))
		return err
	}

	logger.Info("Project index updated in Elasticsearch", zap.Uint64("project_id", projectID))
	return nil
}

// DeleteProjectIndex 从Elasticsearch删除课题索引
func (s *ProjectService) DeleteProjectIndex(projectID uint64) error {
	if s.esClient == nil {
		return fmt.Errorf("elasticsearch client not initialized")
	}

	_, err := s.esClient.Delete().
		Index("projects").
		Id(strconv.FormatUint(projectID, 10)).
		Do(context.Background())

	if err != nil {
		logger.ErrorLog("Failed to delete project index from Elasticsearch",
			zap.Uint64("project_id", projectID),
			zap.Error(err))
		return err
	}

	logger.Info("Project index deleted from Elasticsearch", zap.Uint64("project_id", projectID))
	return nil
}

// CreateProjectIndex 创建Elasticsearch索引
func (s *ProjectService) CreateProjectIndex() error {
	if s.esClient == nil {
		return fmt.Errorf("elasticsearch client not initialized")
	}

	// 定义索引映射
	mapping := `{
		"mappings": {
			"properties": {
				"id": {"type": "long"},
				"title": {"type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart"},
				"description": {"type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart"},
				"requirements": {"type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_smart"},
				"category": {"type": "keyword"},
				"tags": {"type": "text", "analyzer": "ik_max_word"},
				"budget": {"type": "double"},
				"duration": {"type": "integer"},
				"max_applicants": {"type": "integer"},
				"current_applicants": {"type": "integer"},
				"status": {"type": "keyword"},
				"deadline": {"type": "date"},
				"start_date": {"type": "date"},
				"end_date": {"type": "date"},
				"creator_id": {"type": "long"},
				"created_at": {"type": "date"},
				"updated_at": {"type": "date"}
			}
		},
		"settings": {
			"number_of_shards": 1,
			"number_of_replicas": 0,
			"analysis": {
				"analyzer": {
					"ik_max_word": {
						"type": "ik_max_word"
					},
					"ik_smart": {
						"type": "ik_smart"
					}
				}
			}
		}
	}`

	// 检查索引是否存在
	exists, err := s.esClient.IndexExists("projects").Do(context.Background())
	if err != nil {
		return err
	}

	if !exists {
		// 创建索引
		_, err = s.esClient.CreateIndex("projects").BodyString(mapping).Do(context.Background())
		if err != nil {
			logger.ErrorLog("Failed to create Elasticsearch index", zap.Error(err))
			return err
		}
		logger.Info("Elasticsearch index 'projects' created successfully")
	} else {
		logger.Info("Elasticsearch index 'projects' already exists")
	}

	return nil
}

// GetRecommendedProjects 获取推荐的匹配课题列表
func (s *ProjectService) GetRecommendedProjects(studentID uint, topK int) ([]models.RecommendedProject, error) {
	// 1. 获取学生信息
	student, err := s.getStudentInfo(studentID)
	if err != nil {
		return nil, fmt.Errorf("获取学生信息失败: %v", err)
	}

	// 2. 获取可申请的课题列表（状态为open且未达到最大申请人数）
	availableProjects, err := s.getAvailableProjects(studentID)
	if err != nil {
		return nil, fmt.Errorf("获取可申请课题失败: %v", err)
	}

	if len(availableProjects) == 0 {
		return []models.RecommendedProject{}, nil
	}

	// 3. 计算每个课题的匹配分数
	var recommendedProjects []models.RecommendedProject
	for _, project := range availableProjects {
		matchScore := s.calculateMatchScore(student, &project)
		recommendedProjects = append(recommendedProjects, models.RecommendedProject{
			Project:    project,
			MatchScore: matchScore,
		})
	}

	// 4. 按匹配分数排序
	s.sortByMatchScore(recommendedProjects)

	// 5. 返回Top K个课题
	if topK > len(recommendedProjects) {
		topK = len(recommendedProjects)
	}

	return recommendedProjects[:topK], nil
}

// getStudentInfo 获取学生详细信息
func (s *ProjectService) getStudentInfo(studentID uint) (*models.Student, error) {
	var student models.Student
	err := s.db.Preload("User").Where("user_id = ?", studentID).First(&student).Error
	if err != nil {
		return nil, err
	}
	return &student, nil
}

// getAvailableProjects 获取可申请的课题列表
func (s *ProjectService) getAvailableProjects(studentID uint) ([]models.Project, error) {
	var projects []models.Project

	// 查询条件：
	// 1. 课题状态为开放
	// 2. 未达到最大申请人数（如果设置了的话）
	// 3. 截止日期未过
	// 4. 学生未申请过该课题
	query := s.db.Model(&models.Project{}).
		Where("status = ?", models.ProjectStatusOpen).
		Where("deadline > ?", time.Now()).
		Where("(max_applicants = 0 OR current_applicants < max_applicants)").
		Where("id NOT IN (?)",
			s.db.Model(&models.Application{}).
				Select("project_id").
				Where("applicant_id = ?", studentID))

	err := query.Preload("Creator").Find(&projects).Error
	return projects, err
}

// calculateMatchScore 计算学生与课题的匹配分数
func (s *ProjectService) calculateMatchScore(student *models.Student, project *models.Project) float64 {
	var score float64 = 0.0

	// 权重配置
	const (
		researchFieldWeight = 0.3  // 研究方向匹配权重
		skillsWeight        = 0.25 // 技能匹配权重
		majorWeight         = 0.2  // 专业匹配权重
		experienceWeight    = 0.15 // 经验匹配权重
		keywordsWeight      = 0.1  // 关键词匹配权重
	)

	// 1. 研究方向匹配（30%）
	researchFieldScore := s.calculateResearchFieldMatch(student.ResearchField, project.ResearchField, project.Category)
	score += researchFieldScore * researchFieldWeight

	// 2. 技能匹配（25%）
	skillsScore := s.calculateSkillsMatch(student.Skills, project.Requirements, project.Description)
	score += skillsScore * skillsWeight

	// 3. 专业匹配（20%）
	majorScore := s.calculateMajorMatch(student.Major, project.Category, project.Requirements)
	score += majorScore * majorWeight

	// 4. 经验匹配（15%）
	experienceScore := s.calculateExperienceMatch(student.Experience, student.Projects, project.Requirements)
	score += experienceScore * experienceWeight

	// 5. 关键词匹配（10%）
	keywordsScore := s.calculateKeywordsMatch(student, project)
	score += keywordsScore * keywordsWeight

	// 确保分数在0-100之间
	if score > 100 {
		score = 100
	}
	if score < 0 {
		score = 0
	}

	return score
}

// calculateResearchFieldMatch 计算研究方向匹配度
func (s *ProjectService) calculateResearchFieldMatch(studentField, projectField, projectCategory string) float64 {
	if studentField == "" {
		return 20.0 // 如果学生没有填写研究方向，给一个基础分
	}

	// 完全匹配
	if studentField == projectField {
		return 100.0
	}

	// 与课题分类匹配
	if s.isFieldRelated(studentField, projectCategory) {
		return 80.0
	}

	// 模糊匹配（包含关键词）
	similarity := s.calculateStringSimilarity(studentField, projectField+" "+projectCategory)
	return similarity * 60.0
}

// calculateSkillsMatch 计算技能匹配度
func (s *ProjectService) calculateSkillsMatch(studentSkills, projectRequirements, projectDescription string) float64 {
	if studentSkills == "" {
		return 10.0 // 如果学生没有填写技能，给一个很低的基础分
	}

	requirementText := projectRequirements + " " + projectDescription
	studentSkillsList := s.extractSkills(studentSkills)
	requiredSkillsList := s.extractSkills(requirementText)

	if len(requiredSkillsList) == 0 {
		return 50.0 // 如果项目没有明确技能要求，给中等分数
	}

	// 计算技能重合度
	matchCount := 0
	for _, studentSkill := range studentSkillsList {
		for _, requiredSkill := range requiredSkillsList {
			if s.isSkillMatch(studentSkill, requiredSkill) {
				matchCount++
				break
			}
		}
	}

	// 计算匹配百分比
	matchPercentage := float64(matchCount) / float64(len(requiredSkillsList))
	return matchPercentage * 100.0
}

// calculateMajorMatch 计算专业匹配度
func (s *ProjectService) calculateMajorMatch(studentMajor, projectCategory, projectRequirements string) float64 {
	if studentMajor == "" {
		return 30.0
	}

	// 专业与课题分类的映射关系
	majorCategoryMap := map[string][]string{
		"计算机科学与技术": {"人工智能", "软件开发", "数据科学", "网络安全", "机器学习"},
		"软件工程":     {"软件开发", "系统架构", "测试", "移动开发"},
		"数据科学":     {"数据分析", "机器学习", "人工智能", "统计学"},
		"信息管理":     {"信息系统", "项目管理", "商业分析"},
		"电子工程":     {"硬件开发", "嵌入式系统", "物联网"},
		"机械工程":     {"工业设计", "制造", "自动化"},
	}

	relatedCategories, exists := majorCategoryMap[studentMajor]
	if exists {
		for _, category := range relatedCategories {
			if s.containsIgnoreCase(projectCategory, category) ||
				s.containsIgnoreCase(projectRequirements, category) {
				return 90.0
			}
		}
	}

	// 模糊匹配
	similarity := s.calculateStringSimilarity(studentMajor, projectCategory+" "+projectRequirements)
	return similarity * 70.0
}

// calculateExperienceMatch 计算经验匹配度
func (s *ProjectService) calculateExperienceMatch(studentExperience, studentProjects, projectRequirements string) float64 {
	experienceText := studentExperience + " " + studentProjects
	if experienceText == " " || experienceText == "" {
		return 15.0 // 没有经验给基础分
	}

	// 检查经验年限
	experienceLevel := s.extractExperienceLevel(experienceText)
	requiredLevel := s.extractRequiredExperienceLevel(projectRequirements)

	levelScore := 50.0
	if experienceLevel >= requiredLevel {
		levelScore = 80.0
	} else if experienceLevel >= requiredLevel-1 {
		levelScore = 60.0
	}

	// 检查相关项目经验
	projectScore := s.calculateStringSimilarity(experienceText, projectRequirements) * 100.0

	return (levelScore + projectScore) / 2.0
}

// calculateKeywordsMatch 计算关键词匹配度
func (s *ProjectService) calculateKeywordsMatch(student *models.Student, project *models.Project) float64 {
	studentText := student.ResearchField + " " + student.Skills + " " + student.Experience + " " + student.Introduction
	projectText := project.Title + " " + project.Description + " " + project.Requirements + " " + project.Tags

	return s.calculateStringSimilarity(studentText, projectText) * 100.0
}

// 辅助函数

// isFieldRelated 判断研究方向是否相关
func (s *ProjectService) isFieldRelated(studentField, projectCategory string) bool {
	fieldMap := map[string][]string{
		"人工智能": {"机器学习", "深度学习", "自然语言处理", "计算机视觉", "数据挖掘"},
		"软件工程": {"软件开发", "系统设计", "架构设计", "移动开发", "web开发"},
		"数据科学": {"数据分析", "数据挖掘", "统计分析", "大数据", "商业智能"},
		"网络安全": {"信息安全", "密码学", "网络防护", "渗透测试"},
		"物联网":  {"嵌入式系统", "传感器", "智能硬件", "边缘计算"},
	}

	relatedFields, exists := fieldMap[studentField]
	if !exists {
		return false
	}

	for _, field := range relatedFields {
		if s.containsIgnoreCase(projectCategory, field) {
			return true
		}
	}
	return false
}

// extractSkills 提取技能列表
func (s *ProjectService) extractSkills(text string) []string {
	// 常见技能关键词
	skillKeywords := []string{
		"Java", "Python", "JavaScript", "Go", "C++", "C#", "PHP", "Swift", "Kotlin",
		"React", "Vue", "Angular", "Node.js", "Spring", "Django", "Flask",
		"MySQL", "PostgreSQL", "MongoDB", "Redis", "Docker", "Kubernetes",
		"AWS", "Azure", "Git", "Linux", "TensorFlow", "PyTorch", "Spark",
		"机器学习", "深度学习", "数据分析", "前端开发", "后端开发", "移动开发",
		"UI设计", "UX设计", "项目管理", "测试", "运维", "DevOps",
	}

	var foundSkills []string

	for _, skill := range skillKeywords {
		if s.containsIgnoreCase(text, skill) {
			foundSkills = append(foundSkills, skill)
		}
	}

	return foundSkills
}

// isSkillMatch 判断技能是否匹配
func (s *ProjectService) isSkillMatch(studentSkill, requiredSkill string) bool {
	return s.containsIgnoreCase(studentSkill, requiredSkill) ||
		s.containsIgnoreCase(requiredSkill, studentSkill)
}

// extractExperienceLevel 提取经验年限
func (s *ProjectService) extractExperienceLevel(text string) int {
	// 简单的年限提取逻辑，可以根据需要优化
	if s.containsIgnoreCase(text, "3年以上") || s.containsIgnoreCase(text, "资深") {
		return 3
	}
	if s.containsIgnoreCase(text, "2年") || s.containsIgnoreCase(text, "两年") {
		return 2
	}
	if s.containsIgnoreCase(text, "1年") || s.containsIgnoreCase(text, "一年") {
		return 1
	}
	return 0
}

// extractRequiredExperienceLevel 提取要求的经验年限
func (s *ProjectService) extractRequiredExperienceLevel(requirements string) int {
	// 从项目需求中提取所需经验年限
	if s.containsIgnoreCase(requirements, "3年以上") || s.containsIgnoreCase(requirements, "高级") {
		return 3
	}
	if s.containsIgnoreCase(requirements, "2年") || s.containsIgnoreCase(requirements, "中级") {
		return 2
	}
	if s.containsIgnoreCase(requirements, "1年") || s.containsIgnoreCase(requirements, "初级") {
		return 1
	}
	return 0
}

// calculateStringSimilarity 计算字符串相似度（简化版）
func (s *ProjectService) calculateStringSimilarity(str1, str2 string) float64 {
	if str1 == "" || str2 == "" {
		return 0.0
	}

	// 将字符串分割为词汇
	words1 := strings.Fields(strings.ToLower(str1))
	words2 := strings.Fields(strings.ToLower(str2))

	if len(words1) == 0 || len(words2) == 0 {
		return 0.0
	}

	// 计算词汇重合度
	commonWords := 0
	for _, word1 := range words1 {
		for _, word2 := range words2 {
			if word1 == word2 || strings.Contains(word1, word2) || strings.Contains(word2, word1) {
				commonWords++
				break
			}
		}
	}

	// 返回相似度百分比
	similarity := float64(commonWords) / float64(len(words1)+len(words2)-commonWords)
	return similarity
}

// containsIgnoreCase 不区分大小写的包含判断
func (s *ProjectService) containsIgnoreCase(str, substr string) bool {
	return strings.Contains(strings.ToLower(str), strings.ToLower(substr))
}

// sortByMatchScore 按匹配分数排序
func (s *ProjectService) sortByMatchScore(projects []models.RecommendedProject) {
	for i := 0; i < len(projects)-1; i++ {
		for j := 0; j < len(projects)-1-i; j++ {
			if projects[j].MatchScore < projects[j+1].MatchScore {
				projects[j], projects[j+1] = projects[j+1], projects[j]
			}
		}
	}
}
